﻿/*-----------------------------------------------------------------------------------------
   Author               Date            Description
   ----------------------------------------------------------------------------------------
   Steven Applegate     01/30/2011      Initial creation
 ----------------------------------------------------------------------------------------*/

using System;
using System.Web;
using System.Web.Mvc;
using Elmah;

namespace SuddenDeath.Domain.Services.Logging.ELMAH
{
    public class ElmahHandledErrorLoggerFilter : IExceptionFilter
    {
        /// <summary>
        /// Author: Steven Applegate (01/30/2011)
        /// Description: Functionality in the event of an exception
        /// </summary>
        public void OnException(ExceptionContext context)
        {
            var e = context.Exception;
            if (!context.ExceptionHandled   // if unhandled, will be logged anyhow
                || RaiseErrorSignal(e)      // prefer signaling, if possible
                || IsFiltered(context))     // filtered?
                return;

            LogException(e);
        }



        /// <summary>
        /// Author: Steven Applegate (01/30/2011)
        /// Description: Returns true if signaling is preferred for an exception
        /// </summary>
        private static bool RaiseErrorSignal(Exception e)
        {
            var context = HttpContext.Current;
            if (context == null)
                return false;
            var signal = ErrorSignal.FromContext(context);
            if (signal == null)
                return false;
            signal.Raise(e, context);
            return true;
        }



        /// <summary>
        /// Author: Steven Applegate (01/30/2011)
        /// Description: Returns true if an exception is filtered
        /// </summary>
        private static bool IsFiltered(ExceptionContext context)
        {
            var config = context.HttpContext.GetSection("elmah/errorFilter") as ErrorFilterConfiguration;

            if (config == null)
                return false;

            var testContext = new ErrorFilterModule.AssertionHelperContext(context.Exception, HttpContext.Current);

            return config.Assertion.Test(testContext);
        }



        /// <summary>
        /// Author: Steven Applegate (01/30/2011)
        /// Description: Logs an exception
        /// </summary>
        private static void LogException(Exception e)
        {
            var context = HttpContext.Current;
            ErrorLog.GetDefault(context).Log(new Error(e, context));
        }
    }
}
